#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <iostream>

using namespace std;

#define SCORE_BOARD "payoffmatrix"
#define STRATEGIES "strnames"
#define ROUND 100
#define VIEW_BATTLE

int numberofplayers;

int readpayoff(int** payoff)
{
	FILE* fp;
	int ret=0;
	int a,b=0;
	int temp=0;
	fp=fopen(SCORE_BOARD,"r");
	fscanf(fp,"%d",&ret);
	for (a=1; a<=ret; a++)
	{
		for (b=1; b<=ret; b++)
		{
			fscanf(fp,"%d",&temp);
			payoff[a][b]=temp;
		}
	}
	fclose(fp);
	return ret;
}

int readstrname(char** strname)
{
	FILE* fp;
	int cnt=0;
	int x=0;
	fp=fopen(STRATEGIES,"r");
	while(!feof(fp))
	{
		x=fscanf(fp,"%s",strname[cnt]);
		if (x==-1)
		{
			break;
		}
		cnt++;
	}
	fclose(fp);
	return cnt;
}

void initstr(int** str)
{
	int a,b=0;
	for (a=0; a<4002; a++)
	{
		for (b=0; b<30; b++)
		{
			str[a][b]=-1;
		}
		str[a][30]=0;
	}
	return;
}

void printstr(int** playerstr,int entry)
{
	int a,b=0;
	int sw=0;
	cout << "No. " << entry << "\n";
	cout << ".....|.....prev1.........................|.......prev2...................|......................|.....|\n";
	cout << "Turn   myact  youract  myscore  yourscore  myact youract myscore yourscore myaverage youraverage target\n";
	cout << "m  M |                 m   M     m    M                   m  M    m    M     m  M     m     M         \n";
	for (a=0; a<4002; a++)
	{
		sw=0;
		for (b=0; b<31; b++)
		{
			cout << playerstr[a][b] << "  ";
			if(b!=30 && playerstr[a][b]!=-1)
			{
				sw=1;
			}
		}
		if (sw==0)
		{
			break;
		}
		cout << "\n";
	}
	return;
}

void readstr(char** strname,int** playerstr,int entry)
{
	FILE* fp;
	int a,b=0;
	int cnt=0;
	int temp=0;
	int x=0;
	fp=fopen(strname[entry],"r");
	while(!feof(fp))
	{
		for(a=0; a<31; a++)
		{
			x=fscanf(fp,"%d",&temp);
			if (x==-1)
			{
				break;
			}
			playerstr[cnt][a]=temp;
		}
		cnt++;
	}
	fclose(fp);
	return;
}

//			p1act=getaction(player1str,turn,p1prevact,p2prevact,p1prevscore,p2prevscore,
//						p1avscore,p2avscore);

int getaction(int** mystr,int turn,int* myactprev,int* youractprev,int* myscoreprev,int* yourscoreprev,
		float myavscore,float youravscore)
{
	int a=0;
	int b=0;
	int sw=0;
	for (a=0; a<4002; a++)
	{
		sw=0;
		if((mystr[a][0]<=turn && mystr[a][1]>=turn) || (mystr[a][0]==-1 && mystr[a][1]==-1))
		{
			for (b=1; b<5; b++)
			{
				if (mystr[a][b*6-4]!=myactprev[b] && mystr[a][b*6-4]!=-1)
				{
					sw=1;
					break;
				}
				if (mystr[a][b*6-3]!=youractprev[b] && mystr[a][b*6-3]!=-1)
				{
					sw=1;
					break;
				}
				if (
				    (mystr[a][b*6-2] > myscoreprev[b] || mystr[a][b*6-1] < myscoreprev[b])
				   && (mystr[a][b*6-2] != -1 && mystr[a][b*6-1] != -1)
				   )
				{
					sw=1;
					break;
				}
				if (
				    (mystr[a][b*6] > yourscoreprev[b] || mystr[a][b*6+1] < yourscoreprev[b])
				   && (mystr[a][b*6] != -1 && mystr[a][b*6+1] != -1)
				   )
				{
					sw=1;
					break;
				}

			}
			if (sw==0)
			{
				if((mystr[a][26]<=(int) myavscore && mystr[a][27]>=(int) myavscore) 
						|| (mystr[a][26]==-1 && mystr[a][27]==-1))
				{
					if((mystr[a][28]<=(int) youravscore && mystr[a][29]>=(int) youravscore) 
						|| (mystr[a][28]==-1 && mystr[a][29]==-1))
					{
						return mystr[a][30];
					}
				}
			}
		}
	}
	return 0;
}

void printstat(int* lastscore,char** strname)
{
	int a=0;
	cout << " Name\t\tScore\n";
	for (a=0; a<numberofplayers; a++)
	{
		cout << strname[a] << "\t" << lastscore[a] << "\n";
	}
}


int main()
{
	int a=0;
	int b=0;
	int c=0;
	int boardsize=0;
	int** payoff; // 20 x 20 (max)
	char** strname;  // 200 x 30
	int** player1str; // 4002* 31 
	int** player2str; //4002 * 31
	int* lastscore; // 200
	
	int turn=0;
	int p1act=0;
	int p2act=0;
	int p1prevact[5];  // before n turn ( 0 = this turn)
	int p2prevact[5];
	int p1score=0;
	int p2score=0;
	int p1prevscore[5];
	int p2prevscore[5];	
	float p1avscore=0.0;
	float p2avscore=0.0;
	int error1=0;
	int error2=0;
	lastscore = (int*) malloc(sizeof(int*)*200);
	payoff = (int**) malloc(sizeof(int*)*20);
	for (a=0; a<20; a++)
	{
		payoff[a]=(int*) malloc(sizeof(int)*20);
		for (b=0; b<20; b++)
		{
			payoff[a][b]=0;
		}
	}
	strname = (char**) malloc(sizeof(char*)*200);
	for (a=0; a<200; a++)
	{
		lastscore[a]=0;
		strname[a]=(char*) malloc(sizeof(char)*30);
		for (b=0; b<30; b++)
		{
			strname[a][b]=0;
		}
	}
	player1str=(int**) malloc(sizeof(int*)*4002);
	player2str=(int**) malloc(sizeof(int*)*4002);
	for (a=0; a<4002; a++)
	{
		player1str[a]=(int*) malloc(sizeof(int*)*31);
		player2str[a]=(int*) malloc(sizeof(int*)*31);
		for (b=0; b<30; b++)
		{
			player1str[a][b]=-1;
			player2str[a][b]=-1;
		}
		player1str[a][30]=0;
		player2str[a][30]=0;
	}
	boardsize=readpayoff(payoff);
	numberofplayers=readstrname(strname);
	//printf("%d %d\n",boardsize,numberofplayers);
	
	for (a=0; a<numberofplayers; a++)
	{
		initstr(player1str);
		readstr(strname,player1str,a);
		//printstr(player1str,a);
		for (b=a+1; b<numberofplayers; b++)
		{
			initstr(player2str);
			readstr(strname,player2str,b);
			//printstr(player2str,b);
			
			//initround
			turn=1;
			for (c=0; c<5; c++)
			{
				p1prevact[c]=-1;
				p1prevscore[c]=-1;
				p2prevact[c]=-1;
				p2prevscore[c]=-1;
			}
			p1score=0;
			p2score=0;
			p1avscore=-1.0;
			p2avscore=-1.0;

			//round start	
#ifdef VIEW_BATTLE
			cout << "A : " << strname[a] << " B : " << strname[b] << "\n";
			cout << "TURN\tAct.A\tAct.B\tScore.A\tScore.B\tsum.A\tsum.B\n";
#endif
			for(turn=1; turn<=ROUND; turn++)
			{
				error1=0;
				error2=0;
				p1act=getaction(player1str,turn,p1prevact,p2prevact,p1prevscore,p2prevscore,
						p1avscore,p2avscore);
				p2act=getaction(player2str,turn,p2prevact,p1prevact,p2prevscore,p1prevscore,
						p2avscore,p1avscore);

				//cout << p1act << " " << p2act << "\n";
				if(p1act > boardsize || p1act <= 0)
				{
					cout << "ERROR : p1 " << a << " " << p1act << "SAP\n";
					error1=20;
					p1act=1;
				}
				if(p2act > boardsize || p2act <= 0)
				{
					cout << "ERROR : p2 " << b << " " << p2act << "SAP\n";
					error2=20;
					p2act=1;
				}

				p1score=p1score+payoff[p1act][p2act]-error1;
				p2score=p2score+payoff[p2act][p1act]-error2;
#ifdef VIEW_BATTLE
				cout << turn << "\t" << p1act << "\t" << p2act << "\t" << payoff[p1act][p2act]
					<< "\t" << payoff[p2act][p1act] << "\t" << p1score << "\t" << p2score << "\n";
#endif
				p1prevact[0]=p1act;
				p2prevact[0]=p2act;
				p1prevscore[0]=payoff[p1act][p2act];
				p2prevscore[0]=payoff[p2act][p1act];
				for (c=4; c>0; c--)	
				{
					p1prevact[c]=p1prevact[c-1];
					p2prevact[c]=p2prevact[c-1];
					p1prevscore[c]=p1prevscore[c-1];
					p2prevscore[c]=p2prevscore[c-1];
				}

				p1avscore=(float) p1score / (float) turn;
				p2avscore=(float) p2score / (float) turn;

			}
			//round end
			cout << a << " : " << p1score << " " << b << " : " << p2score << "\n";
			lastscore[a]=lastscore[a]+p1score;
			lastscore[b]=lastscore[b]+p2score;	
		}
	}
	
	printstat(lastscore,strname);
	return 0;
}
